package com.quanyan.stadium.service.impl;

import com.quanyan.api.APIResponse;
import com.quanyan.club.service.ClubOpenService;
import com.quanyan.common.Plugin.Page;
import com.quanyan.common.Plugin.PageObj;
import com.quanyan.common.utils.ObjectUtil;
import com.quanyan.mq.client.QcMsgClient;
import com.quanyan.mq.client.reqeust.MqRequestMsg;
import com.quanyan.stadium.api.req.ReqPKGameRankList;
import com.quanyan.stadium.api.req.ReqUserRadarChart;
import com.quanyan.stadium.api.resp.RespPKGameRank;
import com.quanyan.stadium.api.resp.RespUserRadarChart;
import com.quanyan.stadium.api.resp.RespUserScoreRankAndRankList;
import com.quanyan.stadium.biz.redis.UserCategoryScoreCacheDao;
import com.quanyan.stadium.constants.GameConstants;
import com.quanyan.stadium.constants.GradePointsConstants;
import com.quanyan.stadium.entity.TbUserScoreCollect;
import com.quanyan.stadium.entity.TbUserScoreCollectExample;
import com.quanyan.stadium.entity.vo.*;
import com.quanyan.stadium.mapper.TbUserScoreCollectMapper;
import com.quanyan.stadium.mapper.VStadiumUserDefinedMapper;
import com.quanyan.stadium.service.*;
import com.quanyan.stadium.service.commonComponent.BaseService;
import com.quanyan.user.response.RespUserInfoBase;
import com.quanyan.user.response.RespUserInfoDetail;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author dongshenglin
 * @date 2016/7/12  10:05
 */
@Service
public class StadiumIndexServiceImpl implements StadiumIndexService {

    @Autowired
    private VStadiumUserDefinedMapper vStadiumUserDefinedMapper;

    @Autowired
    private UserCategoryScoreCacheDao cacheService;

    @Autowired
    private BaseService baseService;

    @Autowired
    private GradeIntegralService gradeIntegralService;

    @Autowired
    private PointsService pointsService;

    @Autowired
    private QcMsgClient qcMsgClient;

    @Autowired
    private RadarChartService radarChartService;

    @Autowired
    private ClubOpenService clubOpenService;

    @Autowired
    private PKEventService pkEventService;

    @Autowired
    private TbUserScoreCollectMapper tbUserScoreCollectMapper;

    private final static Logger logger = LoggerFactory.getLogger(StadiumIndexServiceImpl.class);

    @Override
    public APIResponse<UserGameCategory> getUserGradeIntegral(Integer uid, Integer gameCategoryId) {
        if(gameCategoryId != GameConstants.CATEGORY_ID_FOOTBALL && gameCategoryId != GameConstants.CATEGORY_ID_BASKETBALL
                && gameCategoryId != GameConstants.CATEGORY_ID_TENNIS && gameCategoryId != GameConstants.CATEGORY_ID_BADMINTON){
            return APIResponse.returnFail("输入的栏目(gameCategoryId)不是足篮网羽其中的一个，请重新确认输入参数");
        }

        UserGameCategory userGameCategory = new UserGameCategory();
        /**
         *  获取用户基本信息
         */
        UserInfo userInfo = new UserInfo();
        RespUserInfoDetail userInfoBase = baseService.queryUserMsg(uid);
        if (null != userInfoBase){
            BeanUtils.copyProperties(userInfoBase,userInfo);
        }
        userGameCategory.setUserInfo(userInfo);

        /**
         * 用户勋章列表
         */
        List<UserMedal>  medalList = baseService.getUserMedalList(gameCategoryId, uid, GradePointsConstants.MEDAL_NUM);
        userGameCategory.setUserMedalList(medalList);

        /**
         * 用户评级信息
         */
        UserGrade userGrade = new UserGrade();
        UserGradeIntegral userGradeIntegral = gradeIntegralService.getUserGradeInfo(uid, gameCategoryId);

        /**
         * 用户上一评级、当前评级、下一评级信息
         */
        GradeInfo gradeInfo = new GradeInfo();
        if (null != userGradeIntegral){
            userGrade.setIntegral(userGradeIntegral.getIntegral());
            userGrade.setGradeIcon(userGradeIntegral.getGradeIcon());
            userGrade.setGrade(userGradeIntegral.getGrade() == null ? "暂无评级":userGradeIntegral.getGrade());
            gradeInfo = this.getGradeInfo(userGradeIntegral,gameCategoryId);
        }
        userGameCategory.setGradeInfo(gradeInfo);

        Integer areaId = 1;
        if (null != userInfo.getAreaId()){
            areaId = userInfo.getAreaId();
        }
        UserGrade grade = this.getUserGrade(uid,gameCategoryId,areaId);
        userGrade.setCityRaking(grade.getCityRaking());
        userGrade.setTotalIntegral(grade.getTotalIntegral());
        userGrade.setClubRaking(grade.getClubRaking());
        userGameCategory.setUserGrade(userGrade);

        /**
         * 用户是否为有加入过俱乐部、用户是否为俱乐部管理员
         */
        boolean isSportClubMember = baseService.isSportClubMember(uid,gameCategoryId);
        boolean isSportClubAdmin = baseService.isSportClubAdmin(uid,gameCategoryId);

        userGameCategory.setIsSportClubMember(isSportClubMember);
        userGameCategory.setIsSportClubAdmin(isSportClubAdmin);

        //获取用户雷达图
        ReqUserRadarChart reqUserRadarChart = new ReqUserRadarChart();
        reqUserRadarChart.setType(gameCategoryId);
        reqUserRadarChart.setUid(uid);
        userGameCategory.setUserRadarChart(this.getUserRadarChart(reqUserRadarChart));

        //最新pk和栏目俱乐部个数
        userGameCategory.setJoinedClubNum(baseService.queryMyClubNumByCategoryId(uid, gameCategoryId));
        userGameCategory.setUserNewestPK(pkEventService.queryUserNewestCreatePK(uid, gameCategoryId));
        return APIResponse.returnSuccess(userGameCategory);
    }

    @Override
    public UserGrade getUserGrade(Integer uid,Integer gameCategoryId,Integer areaId) {
        UserGrade userGrade = new UserGrade();

        //个人排名
        Integer cityRaking = 0;
        try {
            cityRaking = this.getUserScoreRank(uid,gameCategoryId,areaId);
        }catch (Exception e){
            logger.error("服务异常 getUserScoreRank获取不到个人排名数据",e);
        }
        userGrade.setCityRaking(cityRaking);

        //个人总积分
        Integer totalIntegral = pointsService.getPointsByCategoryIdAndUserIds(uid, gameCategoryId);
        userGrade.setTotalIntegral(totalIntegral);

        //俱乐部排名
        Integer clubRaking = 0;
        try {
            clubRaking = clubOpenService.getMaxRankingOfMyClubs(uid,gameCategoryId);
        }catch (Exception e){
            logger.error("dubbo服务异常 clubOpenService.getMaxRankingOfMyClubs",e);
        }
        userGrade.setClubRaking(clubRaking);
        return userGrade;
    }

    @Override
    public RespUserRadarChart getUserRadarChart(ReqUserRadarChart reqUserRadarChart) {
        RespUserRadarChart respUserRadarChart = new RespUserRadarChart();
        try {
            respUserRadarChart = radarChartService.userRadarChart(reqUserRadarChart);
        }catch (Exception e){
            logger.error("用户雷达图调用异常！");
        }
        return respUserRadarChart;
    }

    @Override
    public RespUserScoreRankAndRankList queryPKGameRankList(ReqPKGameRankList reqPKGameRankList, Integer uid) throws InvocationTargetException, IllegalAccessException {
        RespUserScoreRankAndRankList respUserScoreRankAndRankList = new RespUserScoreRankAndRankList();
        respUserScoreRankAndRankList.setOwnRank(this.getUserScoreRank(uid, reqPKGameRankList.getCategoryId(), reqPKGameRankList.getCityId()));
        List<RespPKGameRank> result = new ArrayList<>();
        int total = cacheService.getCategoryScoreRankNumFromCache(reqPKGameRankList.getCityId(), reqPKGameRankList.getCategoryId());
        /**
         * 默认存放两页(永不过期,其他的都是设置一天过期);
         *
         * */
        int curNum = cacheService.getCategoryScoreRankStoreNumFromCache(reqPKGameRankList.getCityId(), reqPKGameRankList.getCategoryId());
        /*开始校验当前的数据,缓存中是否存下一次的数据,没有的话,自动添加*/
        if (total == 0 || (curNum > (reqPKGameRankList.getPageNum()-1)*reqPKGameRankList.getPageSize() && curNum <= reqPKGameRankList.getPageNum()*reqPKGameRankList.getPageSize() && total>curNum)) {
            StadiumNotifyMsg stadiumNotifyMsg = new StadiumNotifyMsg();
            stadiumNotifyMsg.setCategoryId(reqPKGameRankList.getCategoryId());
            stadiumNotifyMsg.setCityId(reqPKGameRankList.getCityId());
            stadiumNotifyMsg.setCurNum(curNum);
            stadiumNotifyMsg.setTotalNum(total);
            MqRequestMsg mqRequestMsg = new MqRequestMsg();
            mqRequestMsg.setTopic(GameConstants.STADIUM_TOPIC_ROUND); //pk分页通知
            mqRequestMsg.setTag(GameConstants.STADIUM_TOPIC_PK_RANK_PAGE);
            mqRequestMsg.setMsgId(GameConstants.STADIUM_TOPIC_PK_RANK_PAGE+"-"+new Date().getTime()); //msgId号.
            mqRequestMsg.setFlag(0);
            mqRequestMsg.setBody(ObjectUtil.toByteArray(stadiumNotifyMsg));
            qcMsgClient.asyncSend(mqRequestMsg);
            logger.info("pk分页发送消息，msgId：{} ", mqRequestMsg.getMsgId());
        }
        if (total < 1 || curNum ==0) {
            total=0;
            respUserScoreRankAndRankList.setPageObj(PageObj.create(total, reqPKGameRankList.getPageNum(), reqPKGameRankList.getPageSize(), result));
            return respUserScoreRankAndRankList;
        }

        List<TbUserScoreCollect> msg = new ArrayList<>();
        if (total > (reqPKGameRankList.getPageNum()+1)*reqPKGameRankList.getPageSize()) {
            msg = cacheService.queryCategoryScoreRankMsgFromCache(reqPKGameRankList.getCityId(), reqPKGameRankList.getCategoryId(), reqPKGameRankList.getPageNum()*reqPKGameRankList.getPageSize(),
                    reqPKGameRankList.getPageSize()*(reqPKGameRankList.getPageNum()+1) - 1);
        }else if (total > (reqPKGameRankList.getPageNum())*reqPKGameRankList.getPageSize() && total <= (reqPKGameRankList.getPageNum()+1)*reqPKGameRankList.getPageSize()) {
            msg = cacheService.queryCategoryScoreRankMsgFromCache(reqPKGameRankList.getCityId(), reqPKGameRankList.getCategoryId(), reqPKGameRankList.getPageSize()*(reqPKGameRankList.getPageNum()),
                    total);
        }else {
            msg = null;
        }
        if (null == msg || msg.size() < 1) {
            respUserScoreRankAndRankList.setPageObj(PageObj.create(total, reqPKGameRankList.getPageNum(), reqPKGameRankList.getPageSize(), result));
            return respUserScoreRankAndRankList;
        }
        List<Integer> uIds = new ArrayList<>();
        for (TbUserScoreCollect tbUserScoreCollect : msg) {
            uIds.add(tbUserScoreCollect.getUid());
        }
        Map<Integer, RespUserInfoBase> uMsg =  baseService.queryUserMsg(uIds);
        int i=0;
        for (TbUserScoreCollect tbUserScoreCollect : msg) {
            RespPKGameRank respPKGameRank = new RespPKGameRank();
            BeanUtils.copyProperties(tbUserScoreCollect,respPKGameRank);
            if (null!=uMsg && null!=uMsg.get(tbUserScoreCollect.getUid())) {
                User user = new User();
                BeanUtils.copyProperties(uMsg.get(tbUserScoreCollect.getUid()),user);
                if (user.getAreaId()>0) {
                    user.setRespCity(baseService.getRespCityById(user.getAreaId()));
                }else if (respPKGameRank.getCityId()!=null && respPKGameRank.getCityId()>0) {
                    user.setRespCity(baseService.getRespCityById(respPKGameRank.getCityId()));
                }
                respPKGameRank.setUser(user);
                respPKGameRank.setRank((reqPKGameRankList.getPageNum())*reqPKGameRankList.getPageSize() + (++i));
                result.add(respPKGameRank);
            }
        }
        respUserScoreRankAndRankList.setPageObj(PageObj.create(total, reqPKGameRankList.getPageNum(), reqPKGameRankList.getPageSize(), result));
        return respUserScoreRankAndRankList;
    }

    @Override
    public RespUserScoreRankAndRankList queryPKGameRankListNotCache(ReqPKGameRankList reqPKGameRankList, Integer uid) {
        RespUserScoreRankAndRankList respUserScoreRankAndRankList = new RespUserScoreRankAndRankList();
        respUserScoreRankAndRankList.setOwnRank(this.getUserScoreRank(uid, reqPKGameRankList.getCategoryId(), reqPKGameRankList.getCityId()));
        TbUserScoreCollectExample example = new TbUserScoreCollectExample();
        TbUserScoreCollectExample.Criteria cr = example.createCriteria();
        cr.andCategoryIdEqualTo(reqPKGameRankList.getCategoryId());
        if (reqPKGameRankList.getCityId()!=null && reqPKGameRankList.getCityId().intValue() != 0) {
            cr.andCityIdEqualTo(reqPKGameRankList.getCityId());
        }
        example.setOrderByClause("score desc, update_time desc, uid asc");
        example.setPage(new Page(reqPKGameRankList.getPageNum()*reqPKGameRankList.getPageSize(), reqPKGameRankList.getPageSize()));
        List<TbUserScoreCollect> rs = tbUserScoreCollectMapper.selectByExample(example);
        if (null == rs || rs.size() < 1) {
            respUserScoreRankAndRankList.setPageObj(PageObj.create(0, reqPKGameRankList.getPageNum(), reqPKGameRankList.getPageSize(), rs));
        }else {
            List<Integer> uIds = new ArrayList<>();
            for (TbUserScoreCollect tbUserScoreCollect : rs) {
                uIds.add(tbUserScoreCollect.getUid());
            }
            List<RespPKGameRank> result = new ArrayList<>();
            Map<Integer, RespUserInfoBase> uMsg =  baseService.queryUserMsg(uIds);
            int i=0;
            for (TbUserScoreCollect tbUserScoreCollect : rs) {
                RespPKGameRank respPKGameRank = new RespPKGameRank();
                BeanUtils.copyProperties(tbUserScoreCollect,respPKGameRank);
                if (null!=uMsg && null!=uMsg.get(tbUserScoreCollect.getUid())) {
                    User user = new User();
                    BeanUtils.copyProperties(uMsg.get(tbUserScoreCollect.getUid()),user);
                    if (ObjectUtil.isNotObjectEmpty(user.getAreaId()) && user.getAreaId().intValue() > 0) {
                        user.setRespCity(baseService.getRespCityById(user.getAreaId()));
                    }else if (respPKGameRank.getCityId()!=null && respPKGameRank.getCityId()>0) {
                        user.setRespCity(baseService.getRespCityById(respPKGameRank.getCityId()));
                    }
                    respPKGameRank.setUser(user);
                    respPKGameRank.setRank((reqPKGameRankList.getPageNum())*reqPKGameRankList.getPageSize() + (++i));
                    result.add(respPKGameRank);
                }
            }
            respUserScoreRankAndRankList.setPageObj(PageObj.create(0, reqPKGameRankList.getPageNum(), reqPKGameRankList.getPageSize(), result));
        }
        return respUserScoreRankAndRankList;
    }

    @Override
    public int getUserScoreRank(Integer uid, Integer categoryId, Integer cityId) {
       /* Integer userRank = cacheService.getUserRankNum(cityId, categoryId, uid);
        if (null!=userRank && userRank.intValue()!=0) {
            return userRank;
        }*/
        Integer rank = vStadiumUserDefinedMapper.getUserScoreRank(categoryId, cityId, uid);
        if (null!=rank && rank.intValue()!=0) {
            /*try{
                cacheService.initUserRankNum(cityId, categoryId, uid, rank);
            }catch (Exception e) {
                logger.debug("initUserRankNum出错,redis存储异常");
            }*/
            return rank;
        }
        return 0;
    }

    @Override
    public int getCurrentIndex(Integer categoryId,Double currentGrade) {
        Integer currentIndex = 1;
        if (null == currentGrade){
            return currentIndex;
        }
        if(currentGrade == 1){
            currentIndex = 0;
        }else{
            if (categoryId == GameConstants.CATEGORY_ID_FOOTBALL&&currentGrade == GameConstants.PEAK_GRADE_FOOTBALL){
                currentIndex = 2;
            }
            if (categoryId == GameConstants.CATEGORY_ID_BASKETBALL&&currentGrade == GameConstants.PEAK_GRADE_BASKETBALL){
                currentIndex = 2;
            }
            if (categoryId == GameConstants.CATEGORY_ID_TENNIS&&currentGrade == GameConstants.PEAK_GRADE_TENNIS){
                currentIndex = 2;
            }
            if (categoryId == GameConstants.CATEGORY_ID_BADMINTON&&currentGrade == GameConstants.PEAK_GRADE_BADMINTON){
                currentIndex = 2;
            }
        }
        return currentIndex;
    }

    @Override
    public GradeInfo getGradeInfo(UserGradeIntegral userGradeIntegral,Integer gameCategoryId) {
        GradeInfo gradeInfo = new GradeInfo();
        gradeInfo.setPreviousGrade(1+"");
        gradeInfo.setPreviousIntegral(1000);
        gradeInfo.setPreviousStars(1);
        gradeInfo.setCurrentIndex(1);
        gradeInfo.setCurrentStars(2);
        gradeInfo.setCurrentGrade(2+"");
        gradeInfo.setCurrentIntegral(1500);
        gradeInfo.setNextIntegral(2000);
        gradeInfo.setNextGrade(3+"");
        gradeInfo.setNextStars(3);
        if (null != userGradeIntegral){
            Double currentLevel = 0.0;
            currentLevel = userGradeIntegral.getLevel();
            //当前位置
            Integer currentIndex = this.getCurrentIndex(gameCategoryId, currentLevel);
            if (currentIndex == 0){
                currentLevel = currentLevel + 1;
            }
            if(currentIndex == 2){
                currentLevel = currentLevel - 1;
            }
            /**
             * 获取当前等级信息
             */
            UserGradeIntegral current = gradeIntegralService.getSingleGrade(currentLevel.intValue(),gameCategoryId);
            if (null != current){
                gradeInfo.setCurrentGrade(current.getLevel()+"");
                gradeInfo.setCurrentIntegral(current.getIntegral());
                gradeInfo.setCurrentStars(current.getStars());
            }

            /**
             * 获取上一评级和下一评级信息
             */
            if (null != currentLevel){
                if (currentLevel == 1){
                    gradeInfo.setPreviousGrade("");
                    gradeInfo.setPreviousStars(0);
                    gradeInfo.setPreviousIntegral(0);
                }else{
                    UserGradeIntegral previous = gradeIntegralService.getSingleGrade(currentLevel.intValue() - 1,gameCategoryId);
                    if (null != previous){
                        gradeInfo.setPreviousGrade(previous.getLevel()+"");
                        gradeInfo.setPreviousStars(previous.getStars());
                        gradeInfo.setPreviousIntegral(previous.getIntegral());
                    }
                }
                UserGradeIntegral next =  gradeIntegralService.getSingleGrade(currentLevel.intValue() + 1,gameCategoryId);
                if (null != next){
                    gradeInfo.setNextGrade(null == next.getLevel() ? currentLevel.toString() : next.getLevel()+"");
                    gradeInfo.setNextStars(null == next.getStars()?0:next.getStars());
                    gradeInfo.setNextIntegral(null == next.getIntegral()?userGradeIntegral.getIntegral():next.getIntegral());
                }
            }
            gradeInfo.setCurrentIndex(currentIndex);
        }
        return gradeInfo;
    }
}
